﻿
/*
类型系统格式:

Utype& type

Btype
Utype Btype
struct name
[n] type
*/

//功能描述:
//关于变量类型的函数
namespace n_PyVarType
{
using System;
using n_PyVdataList;
using n_PyConfig;
using n_PyStructList;
using n_PyET;
using n_OS;

public static class VarType
{
	public const string Root = "#";
	
	//目前这个元件层仅仅用于表示系统存储类型所在, 如 base code
	public const string UserRootUnitName = "I";
	public const string This = "this";
	
	//注意这里只需要和system.txt中的定义元件层次一致即可
	public static string VBase = Root + ".base";
	public static string VCode = Root + ".code";
	
	public const string Pointer = "*";
	public const string Refer = "->";
	
	public const string Array = "[";
	public const string Void = "void";
	public const string Struct = "struct";
	public const string Start = "start";
	
	public const string MemoryAddrType = BaseType.Uint32;
	public const int MemoryAddrWidth = 2;
	
	public static class BaseType
	{
		public const string Uint = "uint";
		public const string Uint8 = Uint + "8";
		public const string Uint16 = Uint + "16";
		public const string Uint24 = Uint + "24";
		public const string Uint32 = Uint + "32";
		
		public const string Sint = "int";
		public const string Sint8 = Sint + "8";
		public const string Sint16 = Sint + "16";
		public const string Sint24 = Sint + "24";
		public const string Sint32 = Sint + "32";
		
		public const string Float = "float";
		
		public const string Bit = "bit";  //注意和Bit类型相关的地方,ConstString中需要修改3个函数
		public const string Bool = "bool";
		
		//判断是否为无符号类型 Uint?
		public static bool isUint( string Type )
		{
			if( Type.StartsWith( Uint ) && Type.IndexOf( ',' ) == -1 ) {
				return true;
			}
			return false;
		}
		
		//判断是否为有符号类型 Sint?
		public static bool isSint( string Type )
		{
			if( Type.StartsWith( Sint ) && Type.IndexOf( ',' ) == -1 ) {
				return true;
			}
			return false;
		}
		
		//获取一个基本类型的存储格式类型, 用于接口读写
		public static string GetInterfaceType( string Type )
		{
			if( Type == Bool || Type == Bit ) {
				return Uint8;
			}
			else if( Type == Sint8 ) {
				return Uint8;
			}
			else if( Type == Sint16 ) {
				return Uint16;
			}
			else if( Type == Sint32 ) {
				return Uint32;
			}
			else {
				return Type;
			}
		}
		
		//获取一个类型的底层类型
		public static string GetDefaultType( string Type )
		{
			switch( Type ) {
				case Bool:		return "bool";
				case Bit:		return "bit";
				case Uint8:		return "uint8";
				case Uint16:	return "uint16";
				case Uint24:	return "uint24";
				case Uint32:	return "uint32";
				case Sint8:		return "sint8";
				case Sint16:	return "sint16";
				case Sint24:	return "sint24";
				case Sint32:	return "sint32";
				case Float:		return "float";
				default:		ET.ShowError( "<GetDefaultType> 未知的类型: " + Type ); return null;
			}
		}
	}
	
	//===================================================
	
	//设置当前的基本类型指向
	public static void SetBaseType( int CPUIndex )
	{
		string Real = null;
		
		Real = Root + "." + UserRootUnitName + CPUIndex + ".sys.base";
		int VbaseIndex = VdataList.GetDirectIndex( VBase );
		VdataList.Get( VbaseIndex ).TargetMemberName = Real;
		
		Real = Root + "." + UserRootUnitName + CPUIndex + ".sys.code";
		int VcodeIndex = VdataList.GetDirectIndex( VCode );
		VdataList.Get( VcodeIndex ).TargetMemberName = Real;
		
	}
	
	//<<基础类>>  判断一个类型是否为基本类型
	public static bool isBase( string Type )
	{
		if( Type.IndexOf( ' ' ) == -1 ) {
			return true;
		}
		return false;
	}
	
	//<<基础类>>  判断一个类型是否为引用类型,包括系统引用
	public static bool isRefer( string Type )
	{
		//如果是基本类型,返回false
		if( isBase( Type ) ) {
			return false;
		}
		//获取前缀值,如果以 Refer 结束则返回 true
		string ForeValue = Type.Remove( Type.IndexOf( ' ' ) );
		if( ForeValue.EndsWith( Refer ) ) {
			return true;
		}
		else {
			return false;
		}
	}
	
	//<<基础类>>  判断一个类型是否为指针类型
	public static bool isPointer( string Type )
	{
		//如果是基本类型,返回false
		if( isBase( Type ) ) {
			return false;
		}
		//获取前缀值,如果以 Refer 结束则返回 true
		string ForeValue = Type.Remove( Type.IndexOf( ' ' ) );
		if( ForeValue.EndsWith( Pointer ) ) {
			return true;
		}
		else {
			return false;
		}
	}
	
	//<<基础类>>  判断一个类型是否为结构体
	public static bool isStruct( string Type )
	{
		if( Type.StartsWith( Struct ) ) {
			return true;
		}
		return false;
	}
	
	//<<基础类>>  判断一个类型是否为数组
	public static bool isArray( string Type )
	{
		//如果是基本类型,返回false
		if( isBase( Type ) ) {
			return false;
		}
		//获取前缀值,如果以 Refer 结束则返回 true
		string ForeValue = Type.Remove( Type.IndexOf( ' ' ) );
		if( ForeValue.StartsWith( Array ) ) {
			return true;
		}
		else {
			return false;
		}
	}
	
	//<<基础类>>  获取一个结构体类型的结构体名称
	public static string GetStructName( string Type )
	{
		int SpaceIndex = Type.IndexOf( ' ' );
		return Type.Remove( 0, SpaceIndex + 1 );
	}
	
	//<<基础类>>  获取一个数组类型的子成员类型,只进入数组的最后一维
	public static string GetArrayMemberType( string Type )
	{
		int SpaceIndex = Type.IndexOf( ' ' );
		return Type.Remove( 0, SpaceIndex + 1 );
	}
	
	//生成一个指向指定类型的指针
	public static string AddPointerForType( string Type )
	{
		return VBase + Pointer + " " + Type;
	}
	
	//<<基础类>>  获取一个指针类型的目标成员类型
	public static string GetPointerMemberType( string Type )
	{
		int SpaceIndex = Type.IndexOf( ' ' );
		return Type.Remove( 0, SpaceIndex + 1 );
	}
	
	//判断一个类型是否为虚拟基本类型, 如 vdatatype uint8
	public static bool isVdata( string Type )
	{
		if( !isBase( Type ) && !isRefer( Type ) && !isStruct( Type ) && !isArray( Type ) ) {
			return true;
		}
		return false;
	}
	
	//===================================================
	
	//<<基础类>>  创建一个类型的系统引用
	public static string AddSysRefer( string Type )
	{
		if( isSysRefer( Type ) ) {
			//return Type;
			throw new Exception( "系统错误:无法创建系统引用的引用:" + Type );
		}
		
		//2013.3.15
		//基本类型加上引用时应该把存储类型补充完整
		if( isBase( Type ) ) {
			Type = VarType.CreatVdataType( VarType.VBase, Type );
		}
		
		return Refer + " " + Type;
	}
	
	//<<基础类>>  判断一个类型是否为内置引用类型
	public static bool isSysRefer( string type )
	{
		if( type.StartsWith( Refer + " " ) ) {
			return true;
		}
		return false;
	}
	
	//把一个引用改为系统引用
	public static string SwitchToSysRefer( string Type )
	{
		if( isRefer( Type ) ) {
			string SourceType = GetSourceTypeFromRefer( Type );
			return AddSysRefer( SourceType );
		}
		else {
			return Type;
		}
	}
	
	//判断一个类型是否为指向虚拟类型引用的系统引用
	public static bool isSysReferForRefer( string Type )
	{
		if( isSysRefer( Type ) ) {
			Type = GetSourceTypeFromRefer( Type );
			if( isRefer( Type ) ) {
				return true;
			}
		}
		return false;
	}
	
	//判断一个类型是否为指向结构体的系统引用
	public static bool isSysReferForStruct( string Type )
	{
		if( isSysRefer( Type ) ) {
			Type = GetSourceTypeFromRefer( Type );
			if( isStruct( Type ) ) {
				return true;
			}
		}
		return false;
	}
	
	//判断一个类型是否为指向数组的系统引用
	public static bool isSysReferForArray( string Type )
	{
		if( isSysRefer( Type ) ) {
			Type = GetSourceTypeFromRefer( Type );
			if( isArray( Type ) ) {
				return true;
			}
		}
		return false;
	}
	
	//判断一个类型是否为指向指针的系统引用
	public static bool isSysReferForPointer( string Type )
	{
		if( isSysRefer( Type ) ) {
			Type = GetSourceTypeFromRefer( Type );
			if( isPointer( Type ) ) {
				return true;
			}
		}
		return false;
	}
	
	//判断一个类型是否为指向虚拟数据的系统引用
	public static bool isSysReferForVdata( string Type )
	{
		if( isSysRefer( Type ) ) {
			Type = GetSourceTypeFromRefer( Type );
			if( isVdata( Type ) ) {
				return true;
			}
		}
		return false;
	}
	
	//===================================================
	
	//<<基础类>>  获取一个类型的汇编运算类型,用于汇编运算库展开
	public static string GetASMType( string Type )
	{
		//是基本类型,返回原类型名
		if( isBase( Type ) ) {
			return VarType.BaseType.GetDefaultType( Type );
		}
		if( isPointer( Type ) ) {
			return VarType.MemoryAddrType;
		}
		//是系统引用,返回地址宽度类型
		if( isSysRefer( Type ) ) {
			Type = GetSourceTypeFromRefer( Type );
			string VdataName = GetStoreType( Type );
			int VdataIndex = VdataList.GetIndex( VdataName );
			string AddrType = VdataList.Get( VdataIndex ).AddrType;
			return VarType.BaseType.GetDefaultType( AddrType );
		}
		
		ET.ShowError( "<GetASMType> " + Type );
		
		//返回虚拟变量类型
		return Type.Replace( " ", "." );
	}
	
	//判断类型的存储类型, 返回其存放的虚数据类型
	public static string GetStoreType( string Type )
	{
		string Stype = GetStoreTypeonce( Type );
		return VdataList.Get( VdataList.GetIndex( Stype ) ).VdataName;
	}
	
	//<<基础类>>  判断类型的存储类型, 返回其存放的虚数据类型
	public static string GetStoreTypeonce( string Type )
	{
		//是基本类型,返回 VarType.VBase
		if( isBase( Type ) ) {
			return VarType.VBase;
		}
		//是系统引用类型,返回 VarType.VBase
		if( isSysRefer( Type ) ) {
			return VarType.VBase;
		}
		//是复合类型
		string[] Cut = Type.Split( ' ' );
		for( int i = 0; i < Cut.Length - 1; ++i ) {
			
			//去掉复合类型的数组标志
			if( Cut[ i ].StartsWith( Array ) ) {
				continue;
			}
			//如果是引用,去掉后面的引用标志
			if(  Cut[ i ].EndsWith( Refer ) ) {
				return Cut[ i ].Remove( Cut[ i ].Length - Refer.Length );
			}
			//如果是指针, 去掉后边的指针标志
			if(  Cut[ i ].EndsWith( Pointer ) ) {
				return Cut[ i ].Remove( Cut[ i ].Length - Pointer.Length );
			}
			//如果是结构体,返回结构体所在的元件类型
			if( Cut[ i ] == Struct ) {
				int StructIndex = StructList.GetIndex( Cut[ i + 1 ] );
				return StructList.Get( StructIndex ).StoreType;
			}
			//到这里说明是基本变量类型
			return Cut[ i ];
		}
		//MessageBox.Show( "<GetStoreType> 无法判断的存储类型: " + Type );
		throw new Exception( "<GetStoreType> 无法判断的存储类型: " + Type );
	}
	
	//判断类型的存储类型是否为Vbase
	public static bool StoreTypeisVbase( string Type )
	{
		int VIndex = VdataList.GetIndex( VarType.VBase );
		string StoreType = VarType.GetStoreType( Type );
		int TestIndex = VdataList.GetIndex( StoreType );
		if( VIndex == TestIndex ) {
			return true;
		}
		return false;
	}
	
	//判断类型的存储类型是否为Vcode
	public static bool StoreTypeisVcode( string Type )
	{
		int VIndex = VdataList.GetIndex( VarType.VCode );
		string StoreType = VarType.GetStoreType( Type );
		int TestIndex = VdataList.GetIndex( StoreType );
		if( VIndex == TestIndex ) {
			return true;
		}
		return false;
	}
	
	//判断两个存储类型是否一致
	public static bool StoreTypeisSame( string vType1, string vType2 )
	{
		int VIndex = VdataList.GetIndex( vType1 );
		int TestIndex = VdataList.GetIndex( vType2 );
		if( VIndex == TestIndex ) {
			return true;
		}
		return false;
	}
	
	//<<基础类>>  获取类型的长度, 省略数组长度时返回 -1, 返回其占用的存储单元数目
	public static int GetSize( string Type )
	{
		//如果是基本类型, 返回基本类型长度 / 系统数据宽度, 不满1个时返回1
		if( isBase( Type ) ) {
			int Length = GetBitSize( Type );
			int VdataIndex = VdataList.GetIndex( VarType.VBase );
			string SysType = VdataList.Get( VdataIndex ).DataType;
			int SysTypeLength = GetBitSize( SysType );
			if( Length % SysTypeLength != 0 ) {
				return 1 + ( Length / SysTypeLength );
			}
			else {
				return Length / SysTypeLength;
			}
		}
		//计算扩展元件类型的数目
		return GetVdataTypeSize( Type );
	}
	
	//<<基础类>>  获取基本类型的长度
	public static int GetBitSize( string Type )
	{
		switch( Type ) {
			case VarType.BaseType.Bit:		return 1;
			case VarType.BaseType.Bool:		return 1;
			case VarType.BaseType.Uint8:	return 8;
			case VarType.BaseType.Uint16:	return 16;
			case VarType.BaseType.Uint24:	return 24;
			case VarType.BaseType.Uint32:	return 32;
			case VarType.BaseType.Sint8:	return 8;
			case VarType.BaseType.Sint16:	return 16;
			case VarType.BaseType.Sint24:	return 24;
			case VarType.BaseType.Sint32:	return 32;
			case VarType.BaseType.Float:	return 32;
			default	: break;
		}
		throw new Exception( "系统错误:GetBaseSize中遇到未知的基本类型: " + Type );
	}
	
	//<<基础类>>  获取扩展类型的长度, 返回数组数目 * 基本类型占据的数目
	static int GetVdataTypeSize( string Type )
	{
		//计算数组的元素数目
		string[] Cut = Type.Split( ' ' );
		int Index = 0;
		int Number = 1;
		while( Cut[ Index ].StartsWith( Array ) ) {
			string SNumber = Cut[ Index ].Remove( 0, Array.Length );
			if( SNumber == "" ) {
				return -1;
			}
			Number *= int.Parse( SNumber );
			++Index;
		}
		string VdataName = Cut[ Index ];
		
		//如果是结构体,返回 数目*结构体尺寸
		if( VdataName == Struct ) {
			int StructIndex = StructList.GetIndex( Cut[ Index + 1 ] );
			return Number * StructList.Get( StructIndex ).Size;
		}
		//如果是指针, 返回指针指向的存储器地址类型
		if( VdataName.EndsWith( Pointer ) ) {
			return VarType.MemoryAddrWidth;
		}
		//如果是普通类型,返回 数目*基本类型长度
		if( !VdataName.EndsWith( Refer ) ) {
			int VdataIndex = VdataList.GetIndex( VdataName );
			int Width = GetBitSize( VdataList.Get( VdataIndex ).DataType );
			int BaseSize = GetBitSize( Cut[ Index + 1 ] );
			if( BaseSize % Width != 0 ) {
				return Number * ( BaseSize / Width + 1 );
			}
			else {
				return Number * ( BaseSize / Width );
			}
		}
		if( VdataName == Refer ) {
			VdataName = VarType.VBase + Refer;
		}
		//到这里说明是数组+指针类型, 返回 数目*指针尺寸
		string ElementType = "";
		for( int i = Index + 1; i < Cut.Length; ++i ) {
			ElementType += Cut[ i ] + " ";
		}
		ElementType = ElementType.TrimEnd( ' ' );					//获取元素类型
		string StoreType = VarType.GetStoreType( ElementType );		//获取元素存放类型
		int eleVdataIndex = VdataList.GetIndex( StoreType );
		string AddrType = VdataList.Get( eleVdataIndex ).AddrType;	//获取元素类型的地址类型
		int BaseSize1 = GetBitSize( AddrType );
		VdataName = VdataName.Remove( VdataName.Length - Refer.Length );
		int VdataIndex1 = VdataList.GetIndex( VdataName );
		int Width1 = GetBitSize( VdataList.Get( VdataIndex1 ).DataType );
		if( BaseSize1 % Width1 != 0 ) {
			return Number * ( BaseSize1 / Width1 + 1 );
		}
		else {
			return Number * ( BaseSize1 / Width1 );
		}
	}
	
	//===================================================
	
	//<<基础类>>  获取一个引用指向的类型
	public static string GetSourceTypeFromRefer( string Type )
	{
		int SpaceIndex = Type.IndexOf( ' ' );
		return Type.Remove( 0, SpaceIndex + 1 );
	}
	
	//获取一个引用指向的结构体类型的结构体名称
	public static string GetStructNameFromRefer( string Type )
	{
		string StructType = GetSourceTypeFromRefer( Type );
		return GetStructName( StructType );
	}
	
	//获取一个引用指向的数组的元素成员类型,只进入数组的第一层
	public static string GetArrayMemberTypeFromRefer( string Type )
	{
		string ArrayType = GetSourceTypeFromRefer( Type );
		return GetArrayMemberType( ArrayType );
	}
	
	//===================================================
	
	//<<基础类>>  为基本类型创建带有前缀的基类用于结构体的成员定义
	public static string CreatVdataType( string VdataType, string Type )
	{
		return VdataType + " " + Type;
	}
	
	//<<基础类>>  获取一个虚拟内置类型的运算类型
	public static string GetTypeFromVdata( string Type )
	{
		int SpaceIndex = Type.IndexOf( ' ' );
		return Type.Remove( 0, SpaceIndex + 1 );
	}
	
	//<<基础类>>  获取一个标准引用类型的地址类型
	public static string GetReferAddressType( string Type )
	{
		//是基本类型,返回原类型名
		if( isBase( Type ) ) {
			if( Type == VarType.BaseType.Bool ) {
				return VarType.BaseType.Bit;
			}
			else {
				//这里不安全
				//return Type.Replace( VarType.BaseType.Sint, VarType.BaseType.Uint );
				return BaseType.GetInterfaceType( Type );
			}
		}
		//一定是引用类型
		if( VarType.isRefer( Type ) ) {
			Type = Type.Remove( 0, Type.IndexOf( ' ' ) + 1 );
			string VdataName = GetStoreType( Type );
			int VdataIndex = VdataList.GetIndex( VdataName );
			return VdataList.Get( VdataIndex ).AddrType;
		}
		throw new Exception( "<GetReferAddressType> 遇到非引用类型: " + Type );
		//return null;
	}
	
	//<<基础类>>  创建一个常量字节型数组
	public static string CreatArray( int Length, string SubType )
	{
		return Array + Length + " " + SubType;
	}
	
	//<<基础类>>  获取数组元素个数,省略长度时返回 -1
	public static int GetArrayNumber( string Types )
	{
		//计算数组的元素数目
		string[] Cut = Types.Split( ' ' );
		int Index = 0;
		int Number = 1;
		while( Cut[ Index ].StartsWith( Array ) ) {
			string SNumber = Cut[ Index ];
			SNumber = SNumber.Remove( 0, Array.Length );
			if( SNumber == "" ) {
				return -1;
			}
			Number *= int.Parse( SNumber );
			++Index;
		}
		return Number;
	}
}
}




